package thread.wang_bao_ling.c15;

import java.util.LinkedList;
import java.util.List;

/**
 * 通过Synchronized实现简单的阻塞队列实现
 * 在@1和@2处执行的wait会进入到同一个条件变量的等待队列，虽然这个示例中队列里不会同时存在两种wait线程
 *
 */
public class SynchronizatizedQueue {

    private List queue = new LinkedList();
    private int limit = 2;


    public synchronized void enq(Object x) throws InterruptedException {
        while (this.queue.size() == this.limit) {
            wait();//@1
        }
        notifyAll();
        this.queue.add(x);
    }

    public synchronized Object deq() throws InterruptedException {
        while (this.queue.size() == 0) {
            wait();//@2
        }
        notifyAll();
        return this.queue.remove(0);
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizatizedQueue queue=new SynchronizatizedQueue();
        deq(queue, "t1",0);
        deq(queue, "t2",0);
        enq(queue, "one", "t3",1000);
        enq(queue, "two", "t4",2000);

    }


    public static void enq(SynchronizatizedQueue queue, Object o, String threadName,int delay) {
        new Thread(() -> {
            try {
                if (delay > 0) {
                    Thread.currentThread().sleep(delay);
                }
                queue.enq(o);
                System.out.println("enq--->"+o);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, threadName).start();
    }

    public static void deq(SynchronizatizedQueue queue, String threadName,int delay) {
        new Thread(() -> {
            try {
                if (delay > 0) {
                    Thread.currentThread().sleep(delay);
                }
                Object o= queue.deq();
                System.out.println("deq--->"+o);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, threadName).start();
    }
}
